package jsmex.gui;
/*
 * ExplorerGUI.java
 *
 * Created on 2. Oktober 2006, 09:46
 *
 *  This file is part of JSmex.
 *
 *  JSmex is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  JSmex is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with Foobar; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */
import com.jhe.hexed.JHexEditor;
import java.awt.event.KeyEvent;
import java.net.MalformedURLException;
import java.net.URL;
import javax.swing.JOptionPane;
import javax.swing.SpinnerNumberModel;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
import javax.swing.tree.DefaultMutableTreeNode;
import java.awt.Cursor;
import jsmex.HelpWindow;
import jsmex.JSmexStatics;
import jsmex.SwingWorker;
import jsmex.function.SmartCardFile;
import jsmex.function.SmartCardFileNode;
import jsmex.function.ExplorerFunctions;
import opencard.core.util.HexString;


//import org.jdesktop.layout.*;

/**
 *
 * @author  Tobias Senger
 */
public class ExplorerGUI extends javax.swing.JFrame {
    
    
    private static jsmex.cardservice.GsmCardService gsmcs;
    //private static cardservice.GeldkarteCardService gsmcs;
    private boolean isMlactive = true;
    private ExplorerFunctions exfunc = null;
    private JHexEditor jHexEditor1 = null;
    private byte[] hexData = new byte[16];
    
    
    /**
     * Creates new form ExplorerGUI
     */
    public ExplorerGUI(ExplorerFunctions exf) {
        exfunc = exf;
        setLocation(100, 100);
        initComponents();
        
        jHexEditor1 = new JHexEditor(hexData);
        jHexEditor1.addKeyListener(new java.awt.event.KeyListener() {
            public void keyTyped(KeyEvent e) {
            }

            public void keyPressed(KeyEvent e) {
                jLabel18.setText("CHANGED!");
                jButton1.setEnabled(true);
            }

            public void keyReleased(KeyEvent e) {
                System.out.println("keyReleased");
            }
            
        });
        jScrollPane1.setViewportView(jHexEditor1);
        
        setTitle(JSmexStatics.jsTitle+"Explorer");
        
        SmartCardFileNode node = (SmartCardFileNode) jTree1.getLastSelectedPathComponent();
        showAttributes(exfunc.getFileProperties(node));
    }
    
    public void setHexData(byte[] hd) {
        if (hd==null)  return;
        jHexEditor1.setNewData(hd);
    }
    
    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
    private void initComponents() {
        jPanel1 = new javax.swing.JPanel();
        statusLabel = new javax.swing.JLabel();
        jProgressBar1 = new javax.swing.JProgressBar();
        jSplitPane1 = new javax.swing.JSplitPane();
        jScrollPane2 = new javax.swing.JScrollPane();
        DefaultMutableTreeNode rootNode =  new DefaultMutableTreeNode("MF");
        javax.swing.tree.DefaultTreeModel treeModel = new javax.swing.tree.DefaultTreeModel(rootNode);
        jTree1 = new javax.swing.JTree(exfunc.getTreeModel());
        jTree1.setSelectionRow(0);
        jSplitPane2 = new javax.swing.JSplitPane();
        jScrollPane1 = new javax.swing.JScrollPane();
        jPanel2 = new javax.swing.JPanel();
        jLabel1 = new javax.swing.JLabel();
        jLabel2 = new javax.swing.JLabel();
        jLabel3 = new javax.swing.JLabel();
        jLabel4 = new javax.swing.JLabel();
        jLabel5 = new javax.swing.JLabel();
        jLabel6 = new javax.swing.JLabel();
        jLabel7 = new javax.swing.JLabel();
        jLabel8 = new javax.swing.JLabel();
        jLabel9 = new javax.swing.JLabel();
        jLabel10 = new javax.swing.JLabel();
        jLabel11 = new javax.swing.JLabel();
        jLabel12 = new javax.swing.JLabel();
        jLabel13 = new javax.swing.JLabel();
        jLabel14 = new javax.swing.JLabel();
        jSeparator2 = new javax.swing.JSeparator();
        jLabel15 = new javax.swing.JLabel();
        jSpinner1 = new javax.swing.JSpinner();
        jLabel16 = new javax.swing.JLabel();
        jLabel17 = new javax.swing.JLabel();
        jLabel18 = new javax.swing.JLabel();
        jButton1 = new javax.swing.JButton();
        jMenuBar1 = new javax.swing.JMenuBar();
        jMenu1 = new javax.swing.JMenu();
        jMenuItem3 = new javax.swing.JMenuItem();
        jMenuItem5 = new javax.swing.JMenuItem();
        jMenuItem4 = new javax.swing.JMenuItem();
        jSeparator1 = new javax.swing.JSeparator();
        jMenuItem1 = new javax.swing.JMenuItem();
        jMenu2 = new javax.swing.JMenu();
        jMenuItem2 = new javax.swing.JMenuItem();
        jMenuItem6 = new javax.swing.JMenuItem();

        jPanel1.setBorder(javax.swing.BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.LOWERED));
        jPanel1.setMaximumSize(new java.awt.Dimension(32767, 10));
        statusLabel.setText("card removed");
        statusLabel.setName("statusLabel");
        statusLabel.getAccessibleContext().setAccessibleName("statusLabel");

        org.jdesktop.layout.GroupLayout jPanel1Layout = new org.jdesktop.layout.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(jPanel1Layout.createSequentialGroup()
                .add(statusLabel, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 177, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, 555, Short.MAX_VALUE)
                .add(jProgressBar1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 160, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(jPanel1Layout.createSequentialGroup()
                .add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(org.jdesktop.layout.GroupLayout.TRAILING, statusLabel, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 19, Short.MAX_VALUE)
                    .add(jPanel1Layout.createSequentialGroup()
                        .add(4, 4, 4)
                        .add(jProgressBar1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 15, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)))
                .addContainerGap())
        );

        jSplitPane1.setDividerLocation(200);
        jSplitPane1.setPreferredSize(new java.awt.Dimension(435, 200));
        jScrollPane2.setMinimumSize(new java.awt.Dimension(200, 22));
        jScrollPane2.setPreferredSize(new java.awt.Dimension(200, 100));
        jTree1.setMaximumSize(new java.awt.Dimension(79, 32000));
        jTree1.addTreeExpansionListener(new javax.swing.event.TreeExpansionListener() {
            public void treeCollapsed(javax.swing.event.TreeExpansionEvent evt) {
            }
            public void treeExpanded(javax.swing.event.TreeExpansionEvent evt) {
                jTree1TreeExpanded(evt);
            }
        });
        jTree1.addTreeSelectionListener(new javax.swing.event.TreeSelectionListener() {
            public void valueChanged(javax.swing.event.TreeSelectionEvent evt) {
                jTree1ValueChanged(evt);
            }
        });
        jTree1.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                jTree1MouseClicked(evt);
            }
        });

        jScrollPane2.setViewportView(jTree1);

        jSplitPane1.setLeftComponent(jScrollPane2);

        jSplitPane2.setBackground(new java.awt.Color(255, 255, 255));
        jSplitPane2.setDividerSize(5);
        jSplitPane2.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT);
        jSplitPane2.setResizeWeight(0.9);
        jSplitPane2.setEnabled(false);
        jScrollPane1.setBackground(new java.awt.Color(255, 255, 255));
        jScrollPane1.setMinimumSize(new java.awt.Dimension(22, 300));
        jScrollPane1.setPreferredSize(new java.awt.Dimension(163, 400));
        jSplitPane2.setLeftComponent(jScrollPane1);

        jPanel2.setMaximumSize(new java.awt.Dimension(32767, 180));
        jPanel2.setMinimumSize(new java.awt.Dimension(200, 180));
        jPanel2.setPreferredSize(new java.awt.Dimension(100, 180));
        jLabel1.setText("File ID:");

        jLabel2.setText("File size:");

        jLabel3.setText("Type of file:");

        jLabel4.setText("Record length:");

        jLabel5.setText("Records:");

        jLabel6.setText("Read AC:");

        jLabel7.setText("Update AC:");

        jLabel8.setText("jLabel8");

        jLabel9.setText("jLabel9");

        jLabel10.setText("jLabel10");

        jLabel11.setText("jLabel11");

        jLabel12.setText("jLabel12");

        jLabel13.setText("jLabel13");

        jLabel14.setText("jLabel14");

        jSeparator2.setOrientation(javax.swing.SwingConstants.VERTICAL);

        jLabel15.setText("select record:");

        jSpinner1.setEnabled(false);
        jSpinner1.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                jSpinner1StateChanged(evt);
            }
        });

        jLabel16.setMaximumSize(new java.awt.Dimension(10, 10));
        jLabel16.setMinimumSize(new java.awt.Dimension(10, 10));
        jLabel16.setPreferredSize(new java.awt.Dimension(10, 10));

        jLabel17.setText("File status:");

        jLabel18.setText("unchanged");

        jButton1.setText("save changes");
        jButton1.setEnabled(false);
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });

        org.jdesktop.layout.GroupLayout jPanel2Layout = new org.jdesktop.layout.GroupLayout(jPanel2);
        jPanel2.setLayout(jPanel2Layout);
        jPanel2Layout.setHorizontalGroup(
            jPanel2Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(jPanel2Layout.createSequentialGroup()
                .addContainerGap()
                .add(jPanel2Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING, false)
                    .add(jLabel4, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 104, Short.MAX_VALUE)
                    .add(jLabel3, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .add(jLabel2, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .add(jLabel1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .add(jLabel5, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .add(jLabel6, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .add(jLabel7, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(jPanel2Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING, false)
                    .add(jLabel10, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 123, Short.MAX_VALUE)
                    .add(jLabel9, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .add(jLabel8, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .add(jLabel11, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .add(jLabel12, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .add(jLabel13, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .add(jLabel14, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .add(46, 46, 46)
                .add(jSeparator2, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 31, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(jPanel2Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING, false)
                    .add(jSpinner1)
                    .add(jLabel15, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(jLabel16, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 25, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(jPanel2Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(jPanel2Layout.createSequentialGroup()
                        .add(jLabel17)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(jLabel18))
                    .add(jButton1))
                .addContainerGap(76, Short.MAX_VALUE))
        );
        jPanel2Layout.setVerticalGroup(
            jPanel2Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(jPanel2Layout.createSequentialGroup()
                .addContainerGap()
                .add(jPanel2Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(jLabel1)
                    .add(jLabel8))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(jPanel2Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(jLabel2)
                    .add(jLabel9))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(jPanel2Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(jLabel3)
                    .add(jLabel10))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(jPanel2Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(jLabel4)
                    .add(jLabel11))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(jPanel2Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(jLabel5)
                    .add(jLabel12))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(jPanel2Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(jLabel6)
                    .add(jLabel13))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(jPanel2Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(jLabel7)
                    .add(jLabel14))
                .addContainerGap(29, Short.MAX_VALUE))
            .add(jPanel2Layout.createSequentialGroup()
                .add(21, 21, 21)
                .add(jPanel2Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(jLabel15)
                    .add(jLabel16, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 13, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                    .add(jLabel17)
                    .add(jLabel18))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(jPanel2Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(jSpinner1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                    .add(jButton1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 23, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                .addContainerGap(117, Short.MAX_VALUE))
            .add(jSeparator2, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 182, Short.MAX_VALUE)
        );
        jSplitPane2.setBottomComponent(jPanel2);

        jSplitPane1.setRightComponent(jSplitPane2);

        jMenu1.setText("File");
        jMenuItem3.setText("Export EF");
        jMenuItem3.setToolTipText("Save EF content to lokal file.");
        jMenuItem3.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItem3ActionPerformed(evt);
            }
        });

        jMenu1.add(jMenuItem3);

        jMenuItem5.setText("Update EF");
        jMenuItem5.setToolTipText("update a EF from a local file");
        jMenuItem5.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItem5ActionPerformed(evt);
            }
        });

        jMenu1.add(jMenuItem5);

        jMenuItem4.setText("select FID manually");
        jMenuItem4.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItem4ActionPerformed(evt);
            }
        });

        jMenu1.add(jMenuItem4);

        jMenu1.add(jSeparator1);

        jMenuItem1.setText("Close");
        jMenuItem1.setToolTipText("Close JSmex Explorer");
        jMenuItem1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItem1ActionPerformed(evt);
            }
        });

        jMenu1.add(jMenuItem1);

        jMenuBar1.add(jMenu1);

        jMenu2.setText("Info");
        jMenuItem2.setText("About");
        jMenuItem2.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItem2ActionPerformed(evt);
            }
        });

        jMenu2.add(jMenuItem2);

        jMenuItem6.setText("Help");
        jMenuItem6.setToolTipText("shows helpfile");
        jMenuItem6.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItem6ActionPerformed(evt);
            }
        });

        jMenu2.add(jMenuItem6);

        jMenuBar1.add(jMenu2);

        setJMenuBar(jMenuBar1);

        org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(jSplitPane1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 896, Short.MAX_VALUE)
            .add(jPanel1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(org.jdesktop.layout.GroupLayout.TRAILING, layout.createSequentialGroup()
                .add(jSplitPane1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 609, Short.MAX_VALUE)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(jPanel1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 23, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
        );
        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void jMenuItem6ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItem6ActionPerformed
        URL index = null;
        try {
            index = new URL("file:helpfiles/explorer.html");
        } catch (MalformedURLException ex) {
            ex.printStackTrace();
        }
        new HelpWindow("Help Window",index);
    }//GEN-LAST:event_jMenuItem6ActionPerformed

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
        
        exfunc.getLogTracer().info("user clicked jButton1 \"save changes\"",this);
        
        SmartCardFileNode node = (SmartCardFileNode) jTree1.getLastSelectedPathComponent();
        byte[] data = jHexEditor1.getData();
        SpinnerNumberModel snm = (SpinnerNumberModel)jSpinner1.getModel();
        int recno = snm.getNumber().intValue();
        exfunc.updateEF(node, data, recno);
        showFileContent(recno);
        jButton1.setEnabled(false);
        jLabel18.setText("unchanged");
    }//GEN-LAST:event_jButton1ActionPerformed

    private void jSpinner1StateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_jSpinner1StateChanged
        SpinnerNumberModel snm = (SpinnerNumberModel)jSpinner1.getModel();
        int value = snm.getNumber().intValue();
        showFileContent(value);
    }//GEN-LAST:event_jSpinner1StateChanged
        
    private void jMenuItem5ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItem5ActionPerformed
        exfunc.getLogTracer().info("user clicked menuitem: File->Update EF",this);
        SmartCardFileNode node = (SmartCardFileNode) jTree1.getLastSelectedPathComponent();
        if (node.isLeaf()) {
            exfunc.updateEF( node );
        } else JOptionPane.showMessageDialog(null, "No EF is selected!\nPlease first select an EF before you try to update.");
    }//GEN-LAST:event_jMenuItem5ActionPerformed
    
    private void jMenuItem4ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItem4ActionPerformed
        exfunc.getLogTracer().info("user clicked menuitem: Edit->select FID manually",this);
        String inputValue = JOptionPane.showInputDialog(this,"Enter a FID (Format: XX XX)");
        SmartCardFileNode node = exfunc.createNewNode(inputValue);
        if (node==null) JOptionPane.showMessageDialog(this, "Couldn't find FID "+ inputValue+" in this directory.");
        else addTreeNode(node);
    }//GEN-LAST:event_jMenuItem4ActionPerformed
    
    private void jMenuItem3ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItem3ActionPerformed
        exfunc.getLogTracer().info("user clicked menuitem: File->Export EF",this);
        SmartCardFileNode node = (SmartCardFileNode) jTree1.getLastSelectedPathComponent();
        if (node.isLeaf()) {
            exfunc.exportEF( node );
        } else JOptionPane.showMessageDialog(null, "No EF is selected!\nPlease first select an EF before you try to export.");
    }//GEN-LAST:event_jMenuItem3ActionPerformed
    
    private void jTree1TreeExpanded(javax.swing.event.TreeExpansionEvent evt) {//GEN-FIRST:event_jTree1TreeExpanded
        
        exfunc.getLogTracer().info("user expanded tree",this);
        TreePath path = evt.getPath();
        final SmartCardFileNode node = (SmartCardFileNode)path.getLastPathComponent();
        
        if (!node.isExplored()) {
            
            jTree1.setEnabled(false);
            setCursor(new Cursor(Cursor.WAIT_CURSOR));
            statusLabel.setText("Exploring tree...");
            
            final SwingWorker worker = new SwingWorker() {
                
                public Object construct() {
                    
                    DefaultTreeModel model = (DefaultTreeModel)jTree1.getModel();
                    node.explore();
                    model.nodeStructureChanged(node);
                    return null;
                }
                
                //Runs on the event-dispatching thread.
                public void finished() {
                    setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
                    statusLabel.setText("ready");
                    jTree1.setEnabled(true);
                }
            };
            worker.start();
        }
    }//GEN-LAST:event_jTree1TreeExpanded
    
    private void jMenuItem2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItem2ActionPerformed
        exfunc.getLogTracer().info("user clicked menuitem: Info->About",this);
        new AboutDialog(this, true);
    }//GEN-LAST:event_jMenuItem2ActionPerformed
    
    private void jTree1MouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jTree1MouseClicked
        if (isMlactive && (evt.getClickCount() == 2) ) {
            exfunc.getLogTracer().info("user doubleclicked on a treenode",this);
            SmartCardFileNode node = (SmartCardFileNode) jTree1.getLastSelectedPathComponent();
            SmartCardFile scf = (SmartCardFile)node.getUserObject();
            int tof = scf.fp.getTof();
            
            if (tof==2||tof==4||tof==6) {
                SpinnerNumberModel snm = new SpinnerNumberModel(1,1,scf.fp.getRecordsCount(),1);
                jSpinner1.setModel(snm);
                jSpinner1.setEnabled(true);
                showFileContent(1);
            }
            else {
                jSpinner1.setEnabled(false);
                showFileContent(-1);
            }
            
            jLabel18.setText("unchanged");
            jButton1.setEnabled(false);
            
        }
    }//GEN-LAST:event_jTree1MouseClicked
    
    /**This method adds a new SmartCardFileNode to the JTree.
     *
     * @param newnode This argument contains the new new SmartCardFileNode.
     */
    private void addTreeNode(SmartCardFileNode newnode) {
        
        exfunc.getLogTracer().info("called method addTreeNode(SmartCardFileNode newnode)",this);
        
        DefaultTreeModel treemodel = (DefaultTreeModel)jTree1.getModel();
        TreePath tp = jTree1.getLeadSelectionPath();
        SmartCardFileNode parentnode = (SmartCardFileNode)tp.getLastPathComponent();
        
        if (parentnode.isLeaf()) {
            tp = tp.getParentPath();
            parentnode = (SmartCardFileNode)tp.getLastPathComponent();
        }
        
        treemodel.insertNodeInto(newnode, parentnode, parentnode.getChildCount()); //add it to the last position
        //jTree1.updateUI();
        TreeNode[] path = treemodel.getPathToRoot(parentnode);
        jTree1.expandPath(new TreePath(path));
    }
    
    /**
     * This method set the JTree diabled, then it call the getFileContent method from
     * the class ExplorerFunctions. Because the reading could take some time, it will be
     * run in a seperate htread which will be created with help of the SwingWorker class.
     * After reading the content it will be shown in the JTextArea and the Jtree will be activated again.
     */
    private void showFileContent(int recno) {
        
        exfunc.getLogTracer().info("called method showFileContent()",this);
        
        SmartCardFileNode node = (SmartCardFileNode) jTree1.getLastSelectedPathComponent();
        if(!node.isLeaf()) return;
        
        jTree1.setEnabled(false);
        setCursor(new Cursor(Cursor.WAIT_CURSOR));
        statusLabel.setText("Reading file...");
        jSpinner1.setEnabled(false);
        
        final int rn = recno;
        
        final SwingWorker worker = new SwingWorker() {
            
            StringBuffer sb = new StringBuffer();
            SmartCardFileNode node = (SmartCardFileNode) jTree1.getLastSelectedPathComponent();
            SmartCardFile scf = (SmartCardFile)node.getUserObject();
                        
            public Object construct() {
                
                byte[] bdata = exfunc.getFileContent(node, rn);
                return bdata;
            }
            
            //Runs on the event-dispatching thread.
            public void finished() {
                byte[] data = (byte[])get();
                setHexData(data);
                setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
                statusLabel.setText("ready");
                jTree1.setEnabled(true);
                if (scf.fp.getTof()!=1) jSpinner1.setEnabled(true);
            }
        };
        worker.start();
    }
    
    
    private void jTree1ValueChanged(javax.swing.event.TreeSelectionEvent evt) {//GEN-FIRST:event_jTree1ValueChanged
        
        exfunc.getLogTracer().info("user selected new treenode",this);
        
        TreePath path = evt.getNewLeadSelectionPath();
        if (path != null) {
            SmartCardFileNode node = (SmartCardFileNode)path.getLastPathComponent();
            jsmex.function.FileProperties fp = exfunc.getFileProperties(node);
            showAttributes(fp);
        }
    }//GEN-LAST:event_jTree1ValueChanged
    
    private void showAttributes(jsmex.function.FileProperties fp)  {
        
        exfunc.getLogTracer().info("called method showAttributes(jsmex.function.FileProperties fp). FID is "+HexString.hexify(fp.getFID()),this);
        
        jLabel8.setText(HexString.hexify(fp.getFID()));
        jLabel9.setText(fp.getFileSize()+" Byte");
        
        switch (fp.getTof()) {
            case 1 : jLabel10.setText("transparent file"); break;
            case 2 : jLabel10.setText("linear fixed file"); break;
            case 4 : jLabel10.setText("linear variable file"); break;
            case 6 : jLabel10.setText("cyclic file");break;
            case 0x38 : jLabel10.setText("DF"); break;
            default : jLabel10.setText("unknown");
        }
        
        jLabel11.setText(fp.getRecordLength()+" Byte");
        jLabel12.setText(Integer.toString(fp.getRecordsCount()));
        //0x00: ALWAYAS;  0x0F: NEVER;  0x01:CHV1;  0x02:CHV2;
        if(fp.getReadAC()==(byte)0x00) jLabel13.setText("ALWAYS");
        else if(fp.getReadAC()==(byte)0x0F) jLabel13.setText("NEVER");
        else if(fp.getReadAC()==(byte)0x01) jLabel13.setText("CHV1");
        else if(fp.getReadAC()==(byte)0x02) jLabel13.setText("CHV2");
        else  jLabel13.setText("undef AC");
        
        if(fp.getUpdateAC()==(byte)0x00) jLabel14.setText("ALWAYS");
        else if(fp.getUpdateAC()==(byte)0x0F) jLabel14.setText("NEVER");
        else if(fp.getUpdateAC()==(byte)0x01) jLabel14.setText("CHV1");
        else if(fp.getUpdateAC()==(byte)0x02) jLabel14.setText("CHV2");
        else  jLabel14.setText("undef AC");
    }
    
    private void jMenuItem1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItem1ActionPerformed
        exfunc.getLogTracer().info("user clicked menuitem: File->Exit",this);
        exfunc.closeGUI();
    }//GEN-LAST:event_jMenuItem1ActionPerformed
    
    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton jButton1;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel10;
    private javax.swing.JLabel jLabel11;
    private javax.swing.JLabel jLabel12;
    private javax.swing.JLabel jLabel13;
    private javax.swing.JLabel jLabel14;
    private javax.swing.JLabel jLabel15;
    private javax.swing.JLabel jLabel16;
    private javax.swing.JLabel jLabel17;
    private javax.swing.JLabel jLabel18;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JLabel jLabel6;
    private javax.swing.JLabel jLabel7;
    private javax.swing.JLabel jLabel8;
    private javax.swing.JLabel jLabel9;
    private javax.swing.JMenu jMenu1;
    private javax.swing.JMenu jMenu2;
    private javax.swing.JMenuBar jMenuBar1;
    private javax.swing.JMenuItem jMenuItem1;
    private javax.swing.JMenuItem jMenuItem2;
    private javax.swing.JMenuItem jMenuItem3;
    private javax.swing.JMenuItem jMenuItem4;
    private javax.swing.JMenuItem jMenuItem5;
    private javax.swing.JMenuItem jMenuItem6;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JProgressBar jProgressBar1;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JSeparator jSeparator1;
    private javax.swing.JSeparator jSeparator2;
    private javax.swing.JSpinner jSpinner1;
    private javax.swing.JSplitPane jSplitPane1;
    private javax.swing.JSplitPane jSplitPane2;
    private javax.swing.JTree jTree1;
    private javax.swing.JLabel statusLabel;
    // End of variables declaration//GEN-END:variables
    
}
